home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / source / dr2d.lha / modulesdr2dw.c < prev    next >
C/C++ Source or Header  |  1992-01-30  |  15KB  |  599 lines

  1. #include "iffp/obj2d.h"
  2.  
  3. /* Forward declarations */
  4. static int
  5.     WriteDRHD( struct IFFhandle *, struct Proj2D * ),
  6.     WriteDASH( struct IFFhandle *, struct Proj2D * ),
  7.     WriteLAYR( struct IFFhandle *, struct Proj2D * ),
  8.     WriteFILL( struct IFFhandle *, struct Proj2D * ),
  9.     WriteFONS( struct IFFhandle *, struct Proj2D * ),
  10.     WriteCMAP( struct IFFhandle *, struct Proj2D * ),
  11.     WriteObj( struct IFFhandle *, struct Obj2D * ),
  12.     WriteATTR( struct IFFhandle *, struct ATTRstruct * ),
  13.     WriteGRUP( struct IFFhandle *, struct Obj2D * ),
  14.     WriteXTRN( struct IFFhandle *, struct Obj2D * ),
  15.     WritePOLY( struct IFFhandle *, struct Obj2D * ),
  16.     WriteTPTH( struct IFFhandle *, struct Obj2D * ),
  17.     WriteSTXT( struct IFFhandle *, struct Obj2D * ),
  18.     WriteVBM( struct IFFhandle *, struct Obj2D * );
  19.  
  20. /* Data area for chunk writing */
  21. static union {
  22.     struct DRHDstruct
  23.     DRHDdata;
  24.     struct FONSstruct
  25.     FONSdata;
  26.     struct GRUPstruct
  27.     GRUPdata;
  28.     struct XTRNstruct
  29.     XTRNdata;
  30.     struct FILLstruct
  31.     FILLdata;
  32.     struct ATTRstruct
  33.     ATTRdata;
  34.     struct BBOXstruct
  35.     BBOXdata;
  36.     struct DASHstruct
  37.     DASHdata;
  38.     struct LAYRstruct
  39.     LAYRdata;
  40.     struct POLYstruct
  41.     POLYdata;
  42.     struct TPTHstruct
  43.     TPTHdata;
  44.     struct STXTstruct
  45.     STXTdata;
  46.     struct VBMstruct
  47.     VBMdata;
  48. }   Data;
  49.  
  50.  
  51.  
  52. int WriteDR2D( struct ParseInfo *PI, struct Proj2D *Conts )
  53. {
  54.     int
  55.     i;
  56.     struct IFFHandle
  57.     *IFF;
  58.     long
  59.     Error;
  60.     struct Obj2D
  61.     *Curr;            /* Current object */
  62.  
  63.     IFF = PI->iff;
  64.  
  65.     /************* Write the file ****************/
  66.     Error = PushChunk( IFF, ID_DR2D, ID_FORM, IFFSIZE_UNKNOWN );
  67.     if( Error ) {
  68.     goto ErrorExit;
  69.     }
  70.  
  71.     /* Write the DRHD chunk */
  72.     Error = WriteDRHD( IFF, Conts );
  73.     if( Error )    goto ErrorExit;
  74.  
  75.     /* Write the FONS chunks */
  76.     Error = WriteFONS( IFF, Conts );
  77.     if( Error )    goto ErrorExit;
  78.  
  79.     /* Write the DASH chunks */
  80.     Error = WriteDASH( IFF, Conts );
  81.     if( Error )    goto ErrorExit;
  82.  
  83.     /* Write the CMAP/CMYK/CNAM chunks */
  84.     Error = WriteCMAP( IFF, Conts );
  85.     if( Error )    goto ErrorExit;
  86.  
  87.     /* Write the FILL chunks */
  88.     Error = WriteFILL( IFF, Conts );
  89.     if( Error )    goto ErrorExit;
  90.  
  91.     /* Write the LAYR chunks */
  92.     Error = WriteLAYR( IFF, Conts );
  93.     if( Error )    goto ErrorExit;
  94.  
  95.     /* Write all of the objects */
  96.     for( i = 0; i < Conts->NumLayer; i++ ) {
  97.     for( Curr = Conts->Objects[i]; Curr; Curr = Curr->Next ) {
  98.         Error = WriteObj( IFF, Curr );
  99.         if( Error )    goto ErrorExit;
  100.     }
  101.     }
  102.  
  103.     /* Pop out of the final context */
  104.     Error = PopChunk( IFF );
  105.     if( Error ) {
  106.     goto ErrorExit;
  107.     }
  108.  
  109.     /************* Normal exit *****************/
  110.     return 0;
  111.  
  112.     /************* Error exit *****************/
  113. ErrorExit :
  114.     return Error;
  115. }
  116.  
  117.  
  118. static int WriteATTR( struct IFFhandle *IFF, struct ATTRstruct *Attr )
  119. {
  120.     struct ATTRstruct
  121.     Attrs;
  122.     int
  123.     Error;
  124.  
  125.     Attrs = *Attr;
  126.     flt2ieee( &Attr->EdgeThick, &Attrs.EdgeThick );
  127.  
  128.     Error = PushChunk( IFF, 0, ID_ATTR, sizeof(struct ATTRstruct) );
  129.     if( Error != 0 )    return Error;
  130.  
  131.     Error = WriteChunkRecords( IFF, &Attrs, sizeof(struct ATTRstruct), 1 );
  132.     if( Error != 1 )    return Error;
  133.  
  134.     Error = PopChunk( IFF );
  135.     if( Error != 0 )    return Error;
  136.  
  137.     return 0;
  138. }
  139.  
  140.  
  141. static int WriteObj( struct IFFhandle *IFF, struct Obj2D *Obj )
  142. {
  143.     switch( Obj->Type ) {
  144.     case ID_CPLY :    case ID_OPLY :
  145.     return WritePOLY( IFF, Obj );
  146.  
  147.     case ID_TPTH :
  148.     return WriteTPTH( IFF, Obj );
  149.  
  150.     case ID_STXT :
  151.     return WriteSTXT( IFF, Obj );
  152.  
  153.     case ID_VBM :
  154.     return WriteVBM( IFF, Obj );
  155.  
  156.     case ID_GRUP :
  157.     return WriteGRUP( IFF, Obj );
  158.  
  159.     case ID_XTRN :
  160.     return WriteXTRN( IFF, Obj );
  161.  
  162.     default :
  163.     return IFFERR_MANGLED;
  164.     }
  165. }
  166.  
  167.  
  168. static int WriteGRUP( struct IFFhandle * IFF, struct Obj2D *Obj )
  169. {
  170.     struct Obj2D
  171.     *Curr;
  172.     int
  173.     Error;
  174.  
  175.     /* Groups are a nested FORM DR2D */
  176.     Error = PushChunk( IFF, ID_DR2D, ID_FORM, IFFSIZE_UNKNOWN );
  177.     if( Error < 0 )    return Error;
  178.  
  179.     /* The first chunk must be a GRUP chunk */
  180.     Error = PushChunk( IFF, 0, ID_GRUP, sizeof(struct GRUPstruct) );
  181.     if( Error < 0 )    return Error;
  182.  
  183.     Data.GRUPdata.NumObjs = Obj->Data.GRUPdata.NumObjs;
  184.     Error = WriteChunkRecords( IFF, &Data.GRUPdata, sizeof(struct GRUPstruct), 1 );
  185.     if( Error != 1 )    return Error;
  186.  
  187.     Error = PopChunk( IFF );
  188.     if( Error != 0 )    return Error;
  189.  
  190.     /* Then follow all of the objects in the group */
  191.     for( Curr = Obj->Data.GRUPdata.Objs; Curr; Curr = Curr->Next ) {
  192.     Error = WriteObj( IFF, Curr );
  193.     if( Error != 0 )    return Error;
  194.     }
  195.  
  196.     /* Exit the nested FORM DR2D */
  197.     Error = PopChunk( IFF );
  198.     if( Error != 0 )    return Error;
  199.  
  200.     return 0;
  201. }
  202.  
  203.  
  204. static int WriteXTRN( struct IFFhandle *IFF, struct Obj2D *Obj )
  205. {
  206.     int
  207.     n, Error;
  208.  
  209.     Data.XTRNdata.ApplCallBacks = Obj->Data.XTRNdata.ApplCallBacks;
  210.     Data.XTRNdata.ApplNameLength = n = Obj->Data.XTRNdata.ApplNameLength;
  211.  
  212.     /* External objects are a nested FORM DR2D */
  213.     Error = PushChunk( IFF, ID_DR2D, ID_FORM, IFFSIZE_UNKNOWN );
  214.     if( Error < 0 )    return Error;
  215.  
  216.     /* The first chunk must be an XTRN chunk */
  217.     Error = PushChunk( IFF, 0, ID_XTRN, sizeof(struct XTRNstruct) + n );
  218.     if( Error < 0 )    return Error;
  219.  
  220.     Error = WriteChunkRecords( IFF, &Data.XTRNdata, sizeof(struct XTRNstruct), 1 );
  221.     if( Error != 1 )    return Error;
  222.     Error = WriteChunkRecords( IFF, Obj->Data.XTRNdata.ApplName, n, 1 );
  223.     if( Error != 1 )    return Error;
  224.  
  225.     Error = PopChunk( IFF );
  226.     if( Error != 0 )    return Error;
  227.  
  228.     /* Then follows the object */
  229.     Error = WriteObj( IFF, Obj->Data.XTRNdata.Obj );
  230.     if( Error != 0 )    return Error;
  231.  
  232.     /* Exit the nested FORM DR2D */
  233.     Error = PopChunk( IFF );
  234.     if( Error != 0 )    return Error;
  235.  
  236.     return 0;
  237. }
  238.  
  239.  
  240. static int WritePOLY( struct IFFhandle *IFF, struct Obj2D *Obj )
  241. {
  242.     int
  243.     i, n,
  244.     Error;
  245.     Coord
  246.     *Coords;
  247.     IEEE
  248.     Pts[2];
  249.  
  250.     Error = WriteATTR( IFF, &Obj->Attrs );
  251.     if( Error != 0 )    return Error;
  252.  
  253.     Data.POLYdata.NumPoints = n = Obj->Data.POLYdata.NumPoints;
  254.  
  255.     /* Enter the CPLY or OPLY context */
  256.     Error = PushChunk( IFF, 0, Obj->Type,
  257.             sizeof(struct POLYstruct) + n*2*sizeof(IEEE) );
  258.     if( Error != 0 )    return Error;
  259.  
  260.     /* Write the number of points */
  261.     Error = WriteChunkRecords( IFF, &Data, sizeof(struct POLYstruct), 1 );
  262.     if( Error != 1 )    return Error;
  263.  
  264.     /* Write the points */
  265.     Coords = Obj->Data.POLYdata.Coords;
  266.     for( i = 0; i < n; i++ ) {
  267.     if( ((long *)Coords)[2*i] == FLT_IND ) {
  268.         ((long *)Pts)[0] = DR2D_IND;
  269.         ((long *)Pts)[1] = ((long *)Coords)[2*i+1];
  270.     }
  271.     else {
  272.         flt2ieee( Coords + 2*i,     Pts );
  273.         flt2ieee( Coords + 2*i + 1, Pts + 1 );
  274.     }
  275.     Error = WriteChunkRecords( IFF, Pts, 2*sizeof(IEEE), 1 );
  276.     if( Error != 1 )    return Error;
  277.     }
  278.  
  279.     /* Exit the context */
  280.     Error = PopChunk( IFF );
  281.     if( Error != 0 )    return Error;
  282.  
  283.     return 0;
  284. }
  285.  
  286.  
  287. static int WriteTPTH( struct IFFhandle *IFF, struct Obj2D *Obj )
  288. {
  289.     int
  290.     i, nc, np, pad,
  291.     Error;
  292.     char
  293.     c = 0;
  294.     Coord
  295.     *Coords;
  296.     IEEE
  297.     Pts[2];
  298.  
  299.     Error = WriteATTR( IFF, &Obj->Attrs );
  300.     if( Error != 0 )    return Error;
  301.  
  302.     np = Obj->Data.TPTHdata.NumPath;
  303.     nc = Obj->Data.TPTHdata.NumChars;
  304.     pad = nc & 1;
  305.  
  306.     /* Push the TPTH context */
  307.     Error = PushChunk( IFF, 0, ID_TPTH,
  308.             sizeof(struct TPTHstruct) + nc + pad + np*2*sizeof(IEEE) );
  309.     if( Error != 0 )    return Error;
  310.  
  311.     /* Write TPTH information */
  312.     Data.TPTHdata.WhichFont = Obj->Data.TPTHdata.WhichFont;
  313.     flt2ieee( &Obj->Data.TPTHdata.Width, &Data.TPTHdata.CharW );
  314.     flt2ieee( &Obj->Data.TPTHdata.Height, &Data.TPTHdata.CharH );
  315.     Data.TPTHdata.NumChars = nc;
  316.     Data.TPTHdata.NumPoints = np;
  317.     Error = WriteChunkRecords( IFF, &Data, sizeof(struct TPTHstruct), 1 );
  318.     if( Error != 1 ) {
  319.     return Error;
  320.     }
  321.  
  322.     /* Write text string */
  323.     Error = WriteChunkRecords( IFF, Obj->Data.TPTHdata.String, nc, 1 );
  324.     if( Error != 1 )    return Error;
  325.  
  326.     /* Write pad character if necessary */
  327.     if( pad ) {
  328.     Error = WriteChunkRecords( IFF, &c, 1, 1 );
  329.     if( Error != 1 )    return Error;
  330.     }
  331.  
  332.     /* Write text path */
  333.     Coords = Obj->Data.TPTHdata.Path;
  334.     for( i = 0; i < np; i++ ) {
  335.     if( ((long *)Coords)[2*i] == FLT_IND ) {
  336.         ((long *)Pts)[0] = DR2D_IND;
  337.         ((long *)Pts)[1] = ((long *)Coords)[2*i+1];
  338.     }
  339.     else {
  340.         flt2ieee( Coords + 2*i,     Pts );
  341.         flt2ieee( Coords + 2*i + 1, Pts + 1 );
  342.     }
  343.     Error = WriteChunkRecords( IFF, Pts, 2*sizeof(IEEE), 1 );
  344.     if( Error != 1 )    return Error;
  345.     }
  346.  
  347.     /* Exit the context */
  348.     Error = PopChunk( IFF );
  349.     if( Error != 0 )    return Error;
  350.  
  351.     return 0;
  352. }
  353.  
  354.  
  355. static int WriteSTXT( struct IFFhandle *IFF, struct Obj2D *Obj )
  356. {
  357.     int
  358.     n,
  359.     Error;
  360.  
  361.     Error = WriteATTR( IFF, &Obj->Attrs );
  362.     if( Error != 0 )    return Error;
  363.  
  364.     n = Obj->Data.STXTdata.NumChars;
  365.  
  366.     /* Push the STXT context */
  367.     Error = PushChunk( IFF, 0, ID_STXT,
  368.             sizeof(struct STXTstruct) + n );
  369.     if( Error != 0 )    return Error;
  370.  
  371.     /* Write STXT information */
  372.     Data.STXTdata.WhichFont = Obj->Data.STXTdata.WhichFont;
  373.     Data.STXTdata.NumChars = n;
  374.     flt2ieee( &Obj->Data.STXTdata.Width, &Data.STXTdata.CharW );
  375.     flt2ieee( &Obj->Data.STXTdata.Height, &Data.STXTdata.CharH );
  376.     flt2ieee( &Obj->Data.STXTdata.XPos, &Data.STXTdata.BaseX );
  377.     flt2ieee( &Obj->Data.STXTdata.YPos, &Data.STXTdata.BaseY );
  378.     flt2ieee( &Obj->Data.STXTdata.Rotation, &Data.STXTdata.Rotation );
  379.     Error = WriteChunkRecords( IFF, &Data, sizeof(struct STXTstruct), 1 );
  380.     if( Error != 1 )    return Error;
  381.  
  382.     /* Write text string */
  383.         Error = WriteChunkRecords( IFF, Obj->Data.STXTdata.String, n, 1 );
  384.     if( Error != 1 ) {
  385.     return Error;
  386.     }
  387.  
  388.     /* Exit the context */
  389.     Error = PopChunk( IFF );
  390.     if( Error != 0 )    return Error;
  391.  
  392.     return 0;
  393. }
  394.  
  395.  
  396. static int WriteVBM( struct IFFhandle *IFF, struct Obj2D *Obj )
  397. {
  398.     int
  399.     n,
  400.     Error;
  401.  
  402.     n = Obj->Data.VBMdata.PathLen;
  403.  
  404.     /* Push the VBM context */
  405.     Error = PushChunk( IFF, 0, ID_VBM,
  406.             sizeof(struct VBMstruct) + n );
  407.     if( Error != 0 )    return Error;
  408.  
  409.     /* Write VBM information */
  410.     Data.VBMdata.PathLen = n;
  411.     flt2ieee( &Obj->Data.VBMdata.XPos, &Data.VBMdata.XPos );
  412.     flt2ieee( &Obj->Data.VBMdata.YPos, &Data.VBMdata.YPos );
  413.     flt2ieee( &Obj->Data.VBMdata.Width, &Data.VBMdata.XSize );
  414.     flt2ieee( &Obj->Data.VBMdata.Height, &Data.VBMdata.YSize );
  415.     flt2ieee( &Obj->Data.VBMdata.Rotation, &Data.VBMdata.Rotation );
  416.     Error = WriteChunkRecords( IFF, &Data, sizeof(struct VBMstruct), 1 );
  417.     if( Error != 1 )    return Error;
  418.  
  419.     /* Write path to bitmap */
  420.     Error = WriteChunkRecords( IFF, Obj->Data.VBMdata.Path, n, 1 );
  421.     if( Error != 1 )    return Error;
  422.  
  423.     /* Exit the context */
  424.     Error = PopChunk( IFF );
  425.     if( Error != 0 )    return Error;
  426.  
  427.     return 0;
  428. }
  429.  
  430.  
  431. static int WriteDRHD( struct IFFhandle *IFF, struct Proj2D *Conts )
  432. {
  433.     int
  434.     Error;
  435.  
  436.     flt2ieee( &Conts->UL_X, &Data.DRHDdata.UL_X );
  437.     flt2ieee( &Conts->UL_Y, &Data.DRHDdata.UL_Y );
  438.     flt2ieee( &Conts->LR_X, &Data.DRHDdata.LR_X );
  439.     flt2ieee( &Conts->LR_Y, &Data.DRHDdata.LR_Y );
  440.  
  441.     Error = PushChunk( IFF, 0, ID_DRHD, sizeof(struct DRHDstruct) );
  442.     if( Error != 0 )    return Error;
  443.  
  444.     Error = WriteChunkRecords( IFF, &Data.DRHDdata, sizeof(struct DRHDstruct), 1 );
  445.     if( Error != 1 )    return Error;
  446.  
  447.     Error = PopChunk( IFF );
  448.     if( Error != 0 )    return Error;
  449.     return 0;
  450. }
  451.  
  452.  
  453. static int WriteDASH( struct IFFhandle *IFF, struct Proj2D *Conts )
  454. {
  455.     int
  456.     i, j, n,
  457.     Error;
  458.     IEEE
  459.     Point;
  460.  
  461.     for( i = 0; i < Conts->NumDash; i++ ) {
  462.     Data.DASHdata.DashID = i;
  463.     Data.DASHdata.NumDashes = n = Conts->DashCounts[i];
  464.  
  465.     /* Enter a new chunk */
  466.     Error = PushChunk( IFF, 0, ID_DASH,
  467.             sizeof(struct DASHstruct) + n*sizeof(IEEE) );
  468.     if( Error != 0 )    return Error;
  469.  
  470.     /* Write the DASH chunk */
  471.     Error = WriteChunkRecords( IFF, &Data.DASHdata,
  472.                 sizeof(struct DASHstruct), 1 );
  473.     if( Error != 1 )    return Error;
  474.     for( j = 0; j < n; j++ ) {
  475.         flt2ieee( Conts->DashPatts[i] + j, &Point );
  476.         Error = WriteChunkRecords( IFF, &Point, sizeof(IEEE), 1 );
  477.         if( Error != 1 )    return Error;
  478.     }
  479.  
  480.     /* Exit the chunk */
  481.     Error = PopChunk( IFF );
  482.     if( Error != 0 )    return Error;
  483.     }
  484.  
  485.     return 0;
  486. }
  487.  
  488.  
  489.  
  490. static int WriteLAYR( struct IFFhandle *IFF, struct Proj2D *Conts )
  491. {
  492.     int
  493.     i,
  494.     Error;
  495.  
  496.     for( i = 0; i < Conts->NumLayer; i++ ) {
  497.     /* Enter a new chunk */
  498.     Error = PushChunk( IFF, 0, ID_LAYR, sizeof(struct LAYRstruct) );
  499.     if( Error != 0 )    return Error;
  500.  
  501.     /* Write the LAYR chunk */
  502.     Error = WriteChunkRecords( IFF, Conts->LayerTable + i,
  503.                 sizeof(struct LAYRstruct), 1 );
  504.     if( Error != 1 )    return Error;
  505.  
  506.     /* Exit the chunk */
  507.     Error = PopChunk( IFF );
  508.     if( Error != 0 )    return Error;
  509.     }
  510.  
  511.     return 0;
  512. }
  513.  
  514.  
  515. static int WriteFILL( struct IFFhandle *IFF, struct Proj2D *Conts )
  516. {
  517.     int
  518.     i,
  519.     Error;
  520.  
  521.     for( i = 0; i < Conts->NumFills; i++ ) {
  522.     /* Fills are a nested FORM DR2D */
  523.     Error = PushChunk( IFF, ID_DR2D, ID_FORM, IFFSIZE_UNKNOWN );
  524.     if( Error < 0 )    return Error;
  525.  
  526.     /* The first chunk must be a FILL chunk */
  527.     Error = PushChunk( IFF, 0, ID_FILL, sizeof(struct GRUPstruct) );
  528.     if( Error < 0 )    return Error;
  529.  
  530.     Data.FILLdata.FillID = i;
  531.     Error = WriteChunkRecords( IFF, &Data.FILLdata, sizeof(struct FILLstruct), 1 );
  532.     if( Error != 1 )    return Error;
  533.  
  534.     Error = PopChunk( IFF );
  535.     if( Error != 0 )    return Error;
  536.  
  537.     /* Then the object of the fill */
  538.     Error = WriteObj( IFF, Conts->FillTable[i] );
  539.     if( Error != 0 )    return Error;
  540.  
  541.     /* Exit the nested FORM DR2D */
  542.     Error = PopChunk( IFF );
  543.     if( Error != 0 )    return Error;
  544.     }
  545.     return 0;
  546. }
  547.  
  548.  
  549. static int WriteFONS( struct IFFhandle *IFF, struct Proj2D *Conts )
  550. {
  551.     int
  552.     i, n,
  553.     Error;
  554.  
  555.     for( i = 0; i < Conts->NumFont; i++ ) {
  556.     /* Enter a new chunk */
  557.     n = strlen( Conts->FontNames[i] ) + 1;
  558.     Error = PushChunk( IFF, 0, ID_FONS, sizeof(struct FONSstruct) + n );
  559.     if( Error != 0 )    return Error;
  560.  
  561.     /* Write the FONS chunk */
  562.     Error = WriteChunkRecords( IFF, Conts->FontTable + i,
  563.                 sizeof(struct FONSstruct), 1 );
  564.     if( Error != 1 )    return Error;
  565.     Error = WriteChunkRecords( IFF, Conts->FontNames[i], n, 1 );
  566.     if( Error != 1 )    return Error;
  567.  
  568.     /* Exit the chunk */
  569.     Error = PopChunk( IFF );
  570.     if( Error != 0 )    return Error;
  571.     }
  572.  
  573.     return 0;
  574. }
  575.  
  576.  
  577. static int WriteCMAP( struct IFFhandle *IFF, struct Proj2D *Conts )
  578. {
  579.     int
  580.     Error;
  581.  
  582.     /* Enter a new chunk */
  583.     Error = PushChunk( IFF, 0, ID_CMAP, 3*Conts->NumColor );
  584.     if( Error != 0 )    return Error;
  585.  
  586.     /* Write the CMAP chunk */
  587.     Error = WriteChunkRecords( IFF, Conts->RGB_Table, 3*Conts->NumColor, 1 );
  588.     if( Error != 1 )    return Error;
  589.  
  590.     /* Exit the chunk */
  591.     Error = PopChunk( IFF );
  592.     if( Error != 0 )    return Error;
  593.  
  594.     return 0;
  595. }
  596.  
  597.  
  598. /*** EOF dr2dw.c ***/
  599.